package com.java1412.controller.api;

import com.alipay.easysdk.factory.Factory;
import com.alipay.easysdk.payment.page.models.AlipayTradePagePayResponse;
import com.java1412.entity.PayInfo;
import com.java1412.entity.User;
import com.java1412.service.CartService;
import com.java1412.service.PayInfoService;
import com.java1412.utils.ConstantUtil;
import com.java1412.utils.ResponseUtil;
import com.java1412.vo.AliPay;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.net.SocketTimeoutException;
import java.net.URLEncoder;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 支付接口的控制器
 *
 * @author java1412
 * @since 2023-08-11 09:32:01
 */
@RestController
@RequestMapping(value = "/alipay")
public class PayController {
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private PayInfoService payInfoService;

    @Resource
    private CartService cartService;

    @RequestMapping(value = "/pay") // 请求的地址subject=xxx&traceNo=xxx&totalAmount=xxx
    public String pay(AliPay aliPay, HttpSession session) {
        AlipayTradePagePayResponse response;
        try {
            // 生成交易编号
            Date nowDate = new Date();
            long tradeNo = nowDate.getTime();
            System.out.println("pay接口生成的交易编号:" + tradeNo);
            // 获取用户编号
            User loginUser = (User) session.getAttribute(ConstantUtil.LOGIN_USER_KEY);
            Integer userId = loginUser.getId();
            // 将交易编号和用户id存到redis中
            stringRedisTemplate.opsForValue().set(tradeNo + "", userId + "");
            // 发起api请求，发起付款
            response = Factory.Payment.Page()
                    .pay(URLEncoder.encode(aliPay.getSubject(), "UTF-8"),
                            tradeNo + "",
                            aliPay.getTotalAmount() + "",
                            "");
        } catch (Exception e) {
            // e.printStackTrace();
            System.out.println("调用遭遇异常，原因:" + e.getMessage());
            throw new RuntimeException(e.getMessage(), e);
        }
        return response.getBody();
    }

    // 支付回调接口本地无法访问，必须要走公网，但是现在没有公网，用内网穿透
    // 回调的接口必须是post请求
    @PostMapping(value = "/notify")
    public String payNotify(HttpServletRequest request) throws Exception {
        // 判断交易的状态
        if (request.getParameter("trade_status").equals("TRADE_SUCCESS")) {
            // 交易是成功
            System.out.println("==============支付宝异步回调===============");
            Map<String, String> params = new HashMap();
            Map<String, String[]> requestMap = request.getParameterMap();
            for (String name : requestMap.keySet()) {
                params.put(name, request.getParameter(name));
            }
            // 获取相应的数据
            String tradeNo = params.get("out_trade_no"); // 交易编号
            String gmtPayment = params.get("gmt_payment"); // 买家的付款时间
            String alipayTradeNo = params.get("trade_no"); // 支付宝交易流水号
            System.out.println("商户订单号:" + tradeNo);
            System.out.println("买家的付款时间:" + gmtPayment);
            System.out.println("支付宝交易流水号:" + alipayTradeNo);
            // 支付宝验签名
            if (Factory.Payment.Common().verifyNotify(params)) {
                // 验签通过
                System.out.println("交易名称:" + params.get("subject"));
                System.out.println("交易状态:" + params.get("trade_status"));
                System.out.println("支付宝交易凭证号:" + params.get("trade_no"));
                System.out.println("商户订单号:" + params.get("out_trade_no"));
                System.out.println("交易金额:" + params.get("total_amount"));
                System.out.println("买家在支付宝唯一id:" + params.get("buyer_id"));
                System.out.println("买家付款时间:" + params.get("gmt_payment"));
                System.out.println("买家付款金额:" + params.get("buyer_pay_amount"));
                // 将数据存在本地数据库
                // 创建PayInfo对象封装数据
                PayInfo payInfo = new PayInfo();
                // 根据交易编号从redis从获取用户编号
                String userId = stringRedisTemplate.opsForValue().get(tradeNo + "");
                payInfo.setUserId(Integer.parseInt(userId));
                // 设置订单号
                payInfo.setOrderNo(Long.parseLong(tradeNo));
                // 设置交易流水号
                payInfo.setPlatformNumber(params.get("trade_no"));
                // 设置交易状态
                payInfo.setPlatformStatus(params.get("trade_status"));
                ResponseUtil r = payInfoService.add(payInfo);
                System.out.println(r);
                // 删除当前用户已支付的购物车中的信息
                ResponseUtil r2 = cartService.deleteByUserId(Integer.parseInt(userId));
                System.out.println(r2);
                // 将redis中的交易编号和用户编号删除
                stringRedisTemplate.delete(tradeNo);
            }
        }
        return "success";
    }
}
